import type { StorageClass, Expire, Result, Data } from "./types";
import { Dictionaries } from "./types";

/**
 * #### 生成存储键名,避免重复，统一增加前缀；
 * @param key 传入的键名
 * @returns 返回拼接后的键名
 */
function createKeyName(key: string) {
  // 将传入的键名转换为大写，并拼接上前缀STORAGE_EXPIRE_
  return `STORAGE_EXPIRE_${key.toUpperCase()}`;
}

/**
 * @description storage类，用于封装localStorage；设置过期时间，并自动删除；
 * @author xm
 * @date 2025-04-15 15:20:00
 * @see https://juejin.cn/post/7188563620601528380
 * @example
 * ```ts
 * const s1 = new Storage();
 * s1.set("a", "123", new Date().getTime() + 5000);
 * setInterval(() => {
 *                    console.log(s1.get("a"));
 *                   },500); // 5秒后，key过期，返回null
 * ```
 */
class Storage implements StorageClass {
  set<T = any>(
    key: string,
    value: T,
    expire: Expire = Dictionaries.permanent
  ): void {
    const data = {
      value,
      [Dictionaries.expire]: expire,
    };
    localStorage.setItem(createKeyName(key), JSON.stringify(data));
  }

  get<T = any>(key: string): Result<T | null> {
    const value = localStorage.getItem(createKeyName(key));
    if (!value) {
      console.warn("key not found");
      return {
        message: "key not found",
        value: null,
      };
    }
    try {
      const obj: Data<T> = JSON.parse(value);
      const now = new Date().getTime();
      if (
        typeof obj[Dictionaries.expire] === "number" &&
        obj[Dictionaries.expire] < now
      ) {
        this.remove(key);
        return {
          message: "key expired",
          value: null,
        };
      } else {
        return {
          message: "success",
          value: obj.value,
        };
      }
    } catch (error) {
      console.warn("parse error");
      return {
        message: "parse error",
        value: null,
      };
    }
  }

  remove(key: string): void {
    localStorage.removeItem(createKeyName(key));
  }

  clear() {
    localStorage.clear();
  }
}

export default Storage;
